package com.joe.codemother.core;

import com.jfinal.template.stat.ast.Return;
import com.joe.codemother.ai.AiCodeGeneratorService;
import com.joe.codemother.ai.model.HtmlCodeResult;
import com.joe.codemother.ai.model.MultiFileCodeResult;
import com.joe.codemother.entity.enums.GenerateTypeEnum;
import com.joe.codemother.exception.BusinessException;
import com.joe.codemother.exception.ErrorCode;
import com.joe.codemother.util.ThrowUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

import java.io.File;

@Service
@Slf4j
public class AiGenerateCodeFacede {

    @Resource
    private AiCodeGeneratorService aiCodeGeneratorService;

    public File generateAiCodePage(String userMessage, GenerateTypeEnum generateType, Long appid){
        ThrowUtils.throwIf(generateType == null, new BusinessException(ErrorCode.PARAMS_ERROR,"RequestType not supported!"));
       return switch (generateType){
           case HTML -> generateHtmlCoed(userMessage,appid);
           case MULTI_FILE -> generateMultiFile(userMessage,appid);
           default -> {
               throw new BusinessException(ErrorCode.PARAMS_ERROR,"the type is not supported" + generateType.getValue());
           }
        };
    }

    private File generateHtmlCoed(String message,Long appId){
        HtmlCodeResult htmlCodeResult = aiCodeGeneratorService.generateHtmlMessage(message);
        return CodeFileSaver.saveHtmlFile(htmlCodeResult,appId);
    }

    private File generateMultiFile(String message, Long appId){
        MultiFileCodeResult multiFileCodeResult = aiCodeGeneratorService.generateMultiFileMessage(message);
        return CodeFileSaver.saveMultipartFile(multiFileCodeResult,appId);
    }

    public Flux<String> generateAiCodeStream(String userMessage, GenerateTypeEnum generateType, Long appId){
        ThrowUtils.throwIf(generateType == null, new BusinessException(ErrorCode.PARAMS_ERROR,"RequestType not supported!"));
        return switch (generateType){
            case HTML -> generateHtmlCodeStream(userMessage,appId);
            case MULTI_FILE -> generateMultiFileStream(userMessage,appId);
            default -> {
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"the type is not supported" + generateType.getValue());
            }
        };
    }

    private Flux<String> generateHtmlCodeStream(String userMessage,Long appId){
        Flux<String> result = aiCodeGeneratorService.generateHtmlMessageStream(userMessage);
        StringBuilder builder = new StringBuilder();
        return result.doOnNext(str -> builder.append(str))
                .doOnComplete(() -> {
                    String finalCode = builder.toString();
                    HtmlCodeResult htmlCodeResult = CodeParser.parseHtmlCode(finalCode);
                    File file = CodeFileSaver.saveHtmlFile(htmlCodeResult,appId);
                    log.info("The file was stored successfully, the code is " + file.getAbsolutePath());
                });
    }

    private Flux<String> generateMultiFileStream(String userMessage,Long appId){
        Flux<String> result = aiCodeGeneratorService.generateMultiFileMessageStream(userMessage);
        StringBuilder builder = new StringBuilder();
        return result.doOnNext(str -> builder.append(str))
                .doOnComplete(() -> {
                    String finalCode = builder.toString();
                    MultiFileCodeResult multiFileCodeResult = CodeParser.parseMultiFileCode(finalCode);
                    File file = CodeFileSaver.saveMultipartFile(multiFileCodeResult,appId);
                    log.info("The file was stored successfully, the code is " + file.getAbsolutePath());
                });
    }

}
